From d1a332d19a6ae10ea84d9f99fb705276fcbffde3 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sun, 21 Sep 2014 14:27:30 -0700 Subject: [PATCH] Make `cargo update` more conservative. As described in #613, this commit switches the semantics of `cargo update foo` to updating *only* `foo`, not any of its dependencies. A new flag, `--aggressive` was added to restore the old behavior. The behavior of attempting to only unlock `foo`, and then if resolve fails unlock all dependencies of `foo` is unimplemented as it's not super relevant right now when the majority of dependencies are git dependencies and resolution cannot fail for version-related reasons. Closes #613 --- src/bin/update.rs | 10 ++++++---- src/cargo/ops/cargo_generate_lockfile.rs | 9 +++++++-- tests/test_cargo_compile_git_deps.rs | 3 +++ 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/bin/update.rs b/src/bin/update.rs index 705832cc0..79bd754de 100644 --- a/src/bin/update.rs +++ b/src/bin/update.rs @@ -14,6 +14,7 @@ Usage: Options: -h, --help Print this message + --aggressive Force updating all dependencies of as well --manifest-path PATH Path to the manifest to compile -v, --verbose Use verbose output @@ -21,9 +22,10 @@ This command requires that a `Cargo.lock` already exists as generated by `cargo build` or related commands. If is specified, then a conservative update of the lockfile will be -performed. This means that only the dependency (and all of its transitive -dependencies) will be updated. All other dependencies will remain locked at -their currently recorded versions. +performed. This means that only the dependency will be updated. Its +transitive dependencies will be updated only if cannot be updated without +updating dependencies. All other dependencies will remain locked at their +currently recorded versions. If is not specified, then all dependencies will be re-resolved and updated. @@ -34,7 +36,7 @@ pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult shell.set_verbose(options.flag_verbose); let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path)); - ops::update_lockfile(&root, shell, options.arg_name) + ops::update_lockfile(&root, shell, options.arg_name, options.flag_aggressive) .map(|_| None).map_err(|err| CliError::from_boxed(err, 101)) } diff --git a/src/cargo/ops/cargo_generate_lockfile.rs b/src/cargo/ops/cargo_generate_lockfile.rs index 44b281289..7e6327d56 100644 --- a/src/cargo/ops/cargo_generate_lockfile.rs +++ b/src/cargo/ops/cargo_generate_lockfile.rs @@ -35,7 +35,8 @@ pub fn generate_lockfile(manifest_path: &Path, pub fn update_lockfile(manifest_path: &Path, shell: &mut MultiShell, - to_update: Option) -> CargoResult<()> { + to_update: Option, + aggressive: bool) -> CargoResult<()> { let mut source = try!(PathSource::for_path(&manifest_path.dir_path())); try!(source.update()); let package = try!(source.get_root_package()); @@ -54,7 +55,11 @@ pub fn update_lockfile(manifest_path: &Path, Some(name) => { let mut to_avoid = HashSet::new(); for dep in resolve.iter().filter(|d| d.get_name() == name.as_slice()) { - fill_with_deps(&resolve, dep, &mut to_avoid); + if aggressive { + fill_with_deps(&resolve, dep, &mut to_avoid); + } else { + to_avoid.insert(dep); + } } resolve.iter().filter(|pkgid| !to_avoid.contains(pkgid)) .map(|pkgid| pkgid.get_source_id().clone()).collect() diff --git a/tests/test_cargo_compile_git_deps.rs b/tests/test_cargo_compile_git_deps.rs index 181de8f9b..941a89052 100644 --- a/tests/test_cargo_compile_git_deps.rs +++ b/tests/test_cargo_compile_git_deps.rs @@ -687,6 +687,9 @@ test!(update_with_shared_deps { timer::sleep(Duration::milliseconds(1000)); assert_that(p.process(cargo_dir().join("cargo")).arg("update").arg("dep1"), + execs().with_stdout("")); + assert_that(p.process(cargo_dir().join("cargo")).arg("update").arg("dep1") + .arg("--aggressive"), execs().with_stdout(format!("{} git repository `{}`", UPDATING, git_project.url()))); -- 2.30.2